package com.thinkingcoder.tcconfig.client.config;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.Ordered;
import org.springframework.core.PriorityOrdered;
import org.springframework.core.env.CompositePropertySource;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;

import lombok.Data;

/**
 * tc property sources processor.
 * 
 * BeanFactoryPostProcessor: bean工厂的后置处理器
 */
@Data
public class PropertySourcesProcessor
    implements BeanFactoryPostProcessor, ApplicationContextAware, EnvironmentAware, PriorityOrdered {

    private static final String TC_PROPERTY_SOURCES = "TcPropertySources";
    private static final String TC_PROPERTY_SOURCE = "TcPropertySource";

    private Environment environment;
    private ApplicationContext applicationContext;

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        ConfigurableEnvironment ENV = (ConfigurableEnvironment)environment;
        if (ENV.getPropertySources().contains(TC_PROPERTY_SOURCES)) {
            return;
        }

        String app = ENV.getProperty("tcconfig.app", "app1");
        String env = ENV.getProperty("tcconfig.env", "dev");
        String ns = ENV.getProperty("tcconfig.ns", "public");
        String configServer = ENV.getProperty("tcconfig.configServer", "http://localhost:9890");

        ConfigMeta configMeta = new ConfigMeta(app, env, ns, configServer);

        TcConfigService configService = TcConfigService.getDefault(applicationContext, configMeta);
        TcPropertySource propertySource = new TcPropertySource(TC_PROPERTY_SOURCE, configService);
        CompositePropertySource composite = new CompositePropertySource(TC_PROPERTY_SOURCES);
        composite.addPropertySource(propertySource);
        ENV.getPropertySources().addFirst(composite);
    }

    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE;
    }
}
